using System;
using System.Collections.Generic;
using System.Text;

using System.Reflection;

namespace Northwind.NET.Utilities
{
    /// <summary>
    /// Provides executing assembly context information
    /// </summary>
    public sealed partial class Context
    {
        /// <summary>
        /// Gets Executing Assembly Name
        /// </summary>
        public static string ExecutingAssemblyName
        {
            get
            {
                Assembly asm = Assembly.GetExecutingAssembly();
                AssemblyName origCodebase = asm.GetName(false);
                return origCodebase.Name;  
            }
        }

        /// <summary>
        /// Gets executing assmbly full path
        /// </summary>
        public static string ExecutingAssemblyFullPath
        {
            get
            {
                Assembly asm = Assembly.GetExecutingAssembly();
                AssemblyName origCodebase = asm.GetName(false);
                string codeBase = origCodebase.CodeBase;
                if (codeBase.StartsWith(@"file:///") || codeBase.StartsWith(@"file:\\\"))
                    codeBase = codeBase.Substring(8);
                return codeBase;
            }
        }
        /// <summary>
        /// Gets executing assembly folder name
        /// </summary>
        public static string ExecutingAssemblyFolderName
        {
            get
            {
                string exeFullPath = ExecutingAssemblyFullPath;
                string folder = (new System.IO.FileInfo(exeFullPath)).DirectoryName;
                if (!folder.EndsWith(@"\")) folder += @"\";
                return folder;
            }
        }

        /// <summary>
        /// Fixes folder name by adding backslash '\' to its ending
        /// </summary>
        /// <param name="folderName">Folder name to fix</param>
        /// <returns></returns>
        public static string FixFolderName(string folderName)
        {
            RunTimeAssert.NotNullOrEmptyString(folderName);
            if (!folderName.EndsWith(@"\")) folderName += @"\";
            return folderName;
        }

        /// <summary>
        /// Makes absolute
        /// </summary>
        /// <param name="possiblyRelativeFolderName"></param>
        /// <returns></returns>
        public static string MakeAbsoluteFolderName(string possiblyRelativeFolderName)
        {
            RunTimeAssert.NotNullOrEmptyString(possiblyRelativeFolderName);
            if (possiblyRelativeFolderName.StartsWith(".."))
            {
                if (string.Compare(possiblyRelativeFolderName, "..", true) == 0)
                {
                    // parent folder
                    System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(Context.ExecutingAssemblyFolderName);
                    possiblyRelativeFolderName = Context.FixFolderName(di.Parent.FullName);
                }
                else
                {
                    System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(Context.ExecutingAssemblyFolderName);
                    possiblyRelativeFolderName = Context.FixFolderName(Context.FixFolderName(di.Parent.FullName) + possiblyRelativeFolderName.Substring(4));
                }
            }
            else if (possiblyRelativeFolderName.StartsWith("."))
            {
                if (string.Compare(possiblyRelativeFolderName, ".", true) == 0)
                {
                    // current executing assembly folder
                    possiblyRelativeFolderName = Context.FixFolderName(Context.ExecutingAssemblyFolderName);
                }
                else
                {
                    // here I assume that a subfolder of a current folder is specified in {{possiblyRelativeFolderName}} 
                    possiblyRelativeFolderName = Context.FixFolderName(Context.FixFolderName(Context.ExecutingAssemblyFolderName) + possiblyRelativeFolderName.Substring(2));
                }
            }
            // we do not check here that {{possiblyRelativeFolderName}} folder exists
            return possiblyRelativeFolderName;
        }
    }
}
